/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gss;

import org.apache.commons.math.fraction.BigFraction;

import java.util.Vector;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author mdm32
 */
public class Vertex {

    private BigFraction xcoord;
    private BigFraction ycoord;
    Vector<String> visibility;
    //private static final double EPSILON = 0.01;

    public Vertex() {
        visibility = new Vector<String>();
        //visibility.add("-1");
        xcoord = new BigFraction(-1);
        ycoord = new BigFraction(-1);
    }

    public Vertex(BigFraction x, BigFraction y) {
        visibility = new Vector<String>();
        xcoord = x;
        ycoord = y;
    }

    public Vertex(Vector<String> vis, BigFraction x, BigFraction y) {
        visibility = vis;
        xcoord = x;
        ycoord = y;
    }

    public Vertex(Vector<String> vis, double x, double y) {
        visibility = vis;
        xcoord = new BigFraction(x);
        ycoord = new BigFraction(y);
    }

    public Vertex(double x, double y) {
        visibility = new Vector<String>();
        xcoord = new BigFraction(x);
        ycoord = new BigFraction(y);
    }

    public Vertex(String name, double x, double y) {
        xcoord = new BigFraction(x);
        ycoord = new BigFraction(y);

        visibility = new Vector<String>();
        visibility.add(name);
    }

    public Vertex(String name, BigFraction x, BigFraction y) {
        xcoord = x;
        ycoord = y;

        visibility = new Vector<String>();
        visibility.add(name);
    }

    public BigFraction getX() {
        return xcoord;
    }

    public BigFraction getY() {
        return ycoord;
    }

    public Vector<String> getVisibility() {
        return visibility;
    }

    public void setX(BigFraction x) {
        xcoord = x;
    }

    public void setY(BigFraction y) {
        ycoord = y;
    }

    public void setX(double x) {
        xcoord = new BigFraction(x);
    }

    public void setY(double y) {
        ycoord = new BigFraction(y);
    }

    public void setVisibility(Vector<String> vis) {
        visibility = vis;
    }

    public boolean equals(Vertex a) {
        if ((a.getX()).equals(xcoord) && (a.getY()).equals(ycoord)) {
            return true;
        } else {
            return false;
        }
    }

    public void printVertex() {
        for (int i = 0; i < visibility.size(); i++) {
            System.out.print(visibility.elementAt(i) + " ");
        }
        System.out.println("(" + xcoord + "," + ycoord + ")");
    }

    public void printVertex2(int numsegs) {
        int a = numsegs - 1;
        for (int i = 0; i < a; i++) {
            if (visibility.contains("" + i)) {
                System.out.print(1 + " ");
            } else {
                System.out.print(0 + " ");
            }
        }

        if (visibility.contains("" + a)) {
            System.out.print(1);
        } else {
            System.out.print(0);
        }
        System.out.println();
    }

    public String asString1() {
        String vert = "" + xcoord.toString() + ", " + ycoord.toString();
        return vert;
    }

    public String asString2(int numsegs) {
        String vert = "";
        int a = numsegs - 1;
        for (int i = 0; i < a; i++) {
            if (visibility.contains("" + i)) {
                vert = vert + "" + 1 + " ";
            } else {
                vert = vert + "" + 0 + " ";
            }
        }

        if (visibility.contains("" + a)) {
            vert = vert + "" + 1;
        } else {
            vert = vert + "" + 0;
        }
        return vert;
    }

    public String toString() {
        String str = "" + xcoord.toString() + ", " + ycoord.toString();
        return str;
    }

    /**
     * Generates a string of space separated 0's and 1's representing the
     * row in the adjacency matrix represented by this Vertex. 
     * @param	seg_names   distinct segment names ordered by their column position
     *			    in the adjacency matrix.
     * @return	string of space separated 0's and 1's representing the
     *		adjacency matrix row
     */
    public String toAdjacencyMatrixRow(List<? extends String> seg_names) {
        // visibility -> 0-1 array
        int ncols = seg_names.size();
        int[] row_array = new int[ncols];
        for (int n : row_array) {
            n = 0;
        }
        Iterator<String> itr = visibility.iterator();
        while (itr.hasNext()) {
            String seg = itr.next();
            int index = seg_names.indexOf(seg);
            row_array[index] = 1;
        }

        // 0-1 array -> String
        String row_string = "";
        for (int n : row_array) {
            row_string = row_string.concat("" + n).concat(" ");
        }

        // remove the last extraneous " " and return
        return row_string.trim();
    }

    /*takes the union of the visibilities of this and b and assign that to a's
     * visibility.  Return a.
     */
    public Vertex mergeVertex(Vertex b) {
        Vertex a = new Vertex();
        Vector<String> avis = visibility;
        for (int i = 0; i < b.getVisibility().size(); i++) {
            if (!(avis.contains(b.getVisibility().elementAt(i)))) {
                avis.add((b.getVisibility()).elementAt(i));
            }
        }
        a.setVisibility(avis);
        a.setX(xcoord);
        a.setY(ycoord);
        return a;
    }

    public double distanceTo(Vertex b) {
        return Math.sqrt((xcoord.doubleValue() - b.getX().doubleValue()) * (xcoord.doubleValue() - b.getX().doubleValue()) + (ycoord.doubleValue() - b.getY().doubleValue()) * (ycoord.doubleValue() - b.getY().doubleValue()));
    }
}
